﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using CTEM.Controllers.BUS;
using CTEM.Models;
using DevExpress.XtraBars;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraEditors.DXErrorProvider;
using DevExpress.XtraEditors.Controls;
using CTEM.Controllers.Global;

namespace CTEM.ModuleForms.ManageWorker
{
    public partial class WorkerSalaryManagement : DevExpress.XtraBars.Ribbon.RibbonForm
    {
        private bool _isNew;
        private bool _isUpdate;
        private bool _isEdit;
        private WorkerSalaryBUS _workerSalaryBUS;
        private WorkerBUS _workerBUS;
        private ConstructionBUS _constructionBus;
        private List<CS_ConstructionDTO> _listConstruction;
       
        private EmployeeBUS _employeeBUS ;
        private List<WorkerSalaryDTO> _listWorkerSalary ;
        private List<WorkerSalaryDTO> _listSalaryHistory;
        private List<EmployerDTO> _listEmployee ;
        private List<WorkerDTO> _listWorker ;



        public WorkerSalaryManagement()
        {
            InitializeComponent();
            gridView1.BestFitColumns();
            _workerSalaryBUS = new WorkerSalaryBUS();
            _employeeBUS = new EmployeeBUS();
            _workerBUS = new WorkerBUS();
            _listWorkerSalary = new List<WorkerSalaryDTO>();
            _listSalaryHistory = new List<WorkerSalaryDTO>();
            _listEmployee = new List<EmployerDTO>();
            _constructionBus = new ConstructionBUS();
            _listConstruction = new List<CS_ConstructionDTO>();
            LoadWorkerSalary();
        }

        public void LoadWorkerSalary()
        {
            _listWorkerSalary = _workerSalaryBUS.LoadAllWks();
            for(int i = 0; i <_listWorkerSalary.Count; i++)
            {
                _listWorkerSalary[i] = ConvertValueForWorkerSalary(_listWorkerSalary[i]);
            }
            workerSalaryDTOBindingSource.DataSource = _listWorkerSalary;
            _listConstruction = _constructionBus.LoadConstruction(true);
            constructionDTOBindingSourse.DataSource = _listConstruction;
        }

        public  WorkerSalaryDTO ConvertValueForWorkerSalary(WorkerSalaryDTO workerSalary)
        {
            
            workerSalary.TotalCost = workerSalary.TotalSalary + workerSalary.OthersCost;

            return workerSalary;
           
        }

        private List<DayWorkingDTO> TimeForWorkingDay(WorkerSalaryDTO workerSalary)
        {
            List<DayWorkingDTO> listDayworking = new List<DayWorkingDTO>();
            TimeSpan numdatespan = workerSalary.ToDate - workerSalary.FromDate;
            int numdates = numdatespan.Days;
            for (int i = 0; i <= numdates; i++)
            {
                DayWorkingDTO dayworking = new DayWorkingDTO();
                dayworking.Date = workerSalary.FromDate.AddDays(i);
                listDayworking.Add(dayworking);
            }
            return listDayworking;
        }

        private void gridView1_InvalidRowException(object sender, DevExpress.XtraGrid.Views.Base.InvalidRowExceptionEventArgs e)
        {
            e.ErrorText = "Bạn nhập sai định dạng dữ liệu";
        }
        private void gridView1_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
        {
            
            if (e.FocusedRowHandle == DevExpress.XtraGrid.GridControl.NewItemRowHandle)
            {

                gridView1.OptionsBehavior.ReadOnly = false;
                _isNew = true;

            }
            else
            {

                gridView1.OptionsBehavior.ReadOnly = !_isEdit;

            }
        }
        private bool ValidateWorkerSalary(WorkerSalaryDTO workerSalary, out String  message, out int  i)
        {

            if (workerSalary.ConstructionID <= 0) 
            {
                message = "bạn chưa chọn công trình";
                i = 1;
                return false;
            }
            if (workerSalary.Manager == null || workerSalary.Manager =="")
            {
                message = "bạn chưa nhập tên quản lý";
                i = 1;
                return false;
            }
            else if (workerSalary.Name == null || workerSalary.Name == "")
            {
                message = "bạn chưa nhập tên cho bảng lương";
                i = 3;
                return false;
            }
            else if (workerSalary.FromDate > workerSalary.ToDate)
            {
                message = "khoảng thời gian chọn cho bảng lương sai";
                i = 4;
                return false;
            }
            else if (workerSalary.OthersCost<0)
            {
                message = "chi phí khác phải lớn hơn 0";
                i = 7;
                return false;
            }
        

            message = "";
            i = 0;
            return true;
        }
        private int ValidateUpdateWorkerSalary(WorkerSalaryDTO workerSalary, out String message, out int i)
        {
            WorkerSalaryDTO ws = _workerSalaryBUS.LoadWSByWorkerSalaryID(workerSalary.WorkersSalaryID);
            
            if (workerSalary.ConstructionID <= 0)
            {
                message = "bạn chưa chọn công trình";
                i = 1;
                return 1;
            }
            if (workerSalary.Manager == null || workerSalary.Manager == "")
            {
                message = "bạn chưa nhập tên quản lý";
                i = 1;
                return 1;
            }
            else if (workerSalary.Name == null || workerSalary.Manager == "")
            {
                message = "bạn chưa nhập tên cho bảng lương";
                i = 3;
                return 1;
            }
            else if (workerSalary.OthersCost < 0)
            {
                message = "chi phí khác phải lớn hơn hoặc bằng 0";
                i = 7;
                return 1;
            }
            
            else if (ws.FromDate != workerSalary.FromDate)
            {
                DialogResult result = MessageBox.Show("Bạn đã thay đỗi thông tin cột 'từ ngày.' \nDữ liệu ngày tháng chấm công đả có sẻ bị thay đổi. \nBạn có muốn thay đổi. ", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                if (result == DialogResult.No)
                {
                    gridView1.SetFocusedRowCellValue("FromDay", ws.FromDate);
                }
                else
                {
                    if (workerSalary.FromDate > workerSalary.ToDate)
                    {
                        message = "khoảng thời gian chọn cho bảng lương sai";
                        i = 4;
                        return 1;
                    }
                    else
                    {
                        message = "";
                        i = 0;
                        return 2;
                    }
                }
            }
            else if (ws.ToDate != workerSalary.ToDate)
            {
                DialogResult result = MessageBox.Show("Bạn đã thay đỗi thông tin cột 'đến ngày.' \nDữ liệu ngày tháng chấm công đả có sẻ bị thay đổi. \nBạn có muốn thay đổi. ", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                if (result == DialogResult.No)
                {
                    gridView1.SetFocusedRowCellValue("ToDay", ws.FromDate);
                }
                else
                {
                    if (workerSalary.FromDate > workerSalary.ToDate)
                    {
                        message = "khoảng thời gian chọn cho bảng lương sai";
                        i = 4;
                        return 1;
                    }
                    else
                    {
                        message = "";
                        i = 0;
                        return 2;
                    }
                }
            }
            else if (workerSalary.FromDate > workerSalary.ToDate)
            {
                message = "khoảng thời gian chọn cho bảng lương sai";
                i = 4;
                return 1;
            }
            message = "";
            i = 0;
            return 0;
        }

        private void gridView1_ValidateRow(object sender, DevExpress.XtraGrid.Views.Base.ValidateRowEventArgs e)
        {
            if (_isNew)
            {

                var view = sender as ColumnView;
                var workerSalary = e.Row as WorkerSalaryDTO;

               
                string message;
                long total = 0;
                int pos;

                
                if (!ValidateWorkerSalary(workerSalary, out message, out pos))
                {
                    e.Valid = false;
                    if (view != null)
                    {
                        view.ClearColumnErrors();
                        view.SetColumnError(view.Columns[pos], message, ErrorType.Warning);
                    }
                    DialogResult result = MessageBox.Show(message + "\nBạn có muốn nhập lại thông tin", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                    if (result == DialogResult.No)
                    {
                        _isNew = false;
                        e.Valid = true;
                        LoadWorkerSalary();
                    }
                }
                else
                {
                   
             
                    ConvertValueForWorkerSalary(workerSalary);
                    try
                    {
                        workerSalary.WorkersSalaryID =_workerSalaryBUS.CreateWks(workerSalary);
                        alertControlMain.Show(this, Constants.CONFIRM, String.Format("Bạn Đã Tạo Mới bảng lương công nhân {0} Thành Công!", workerSalary.Name));
                        workerSalary.Status = 1;
                        _listSalaryHistory.Add(workerSalary);
                        _isNew = false;
                        LoadWorkerSalary();
                    }
                    catch
                    {

                        e.Valid = false;
                        DialogResult result = MessageBox.Show("Bạn xem lại kết nối tới máy chủ \nBạn có muốn nhập lại thông tin", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                        if (result == DialogResult.No)
                        {
                            _isNew = false;
                            e.Valid = true;
                            LoadWorkerSalary();
                        }
                    }
                       
                    

                }
            }
        }

        private void gridView1_InitNewRow(object sender, DevExpress.XtraGrid.Views.Grid.InitNewRowEventArgs e)
        {
            _isNew = true;
            gridView1.SetRowCellValue(e.RowHandle, "CreatedDate", DateTime.Today);
            gridView1.SetRowCellValue(e.RowHandle, "LastUpdate", DateTime.Today);
            gridView1.SetRowCellValue(e.RowHandle, "FromDate", DateTime.Today);
            gridView1.SetRowCellValue(e.RowHandle, "ToDate", DateTime.Today);
            
            gridView1.SetRowCellValue(e.RowHandle, "Reason", "");
            gridView1.SetRowCellValue(e.RowHandle, "Task", "");
        }

        private void WorkerSalaryManagement_Load(object sender, EventArgs e)
        {
            LoadWorkerSalary();
            _isEdit = false;
        }

        private void bntEdit_ItemClick(object sender, ItemClickEventArgs e)
        {
            gridView1.OptionsBehavior.ReadOnly = false;
        }

        private void gridView1_CellValueChanged(object sender, CellValueChangedEventArgs e)
        {
            if (!_isNew)
            {
                var view = sender as ColumnView;
                var i = e.RowHandle;
                var workerSalary = gridView1.GetRow(i) as WorkerSalaryDTO;


                if (workerSalary != null)
                {
                    
                    string message;
                    int pos;
                    int flag = ValidateUpdateWorkerSalary(workerSalary, out message, out pos);
                    if (flag == 1)
                    {
                        DialogResult result = MessageBox.Show(message + "\nBạn có muốn nhập lại thông tin", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                        view.SetColumnError(view.Columns[pos], message, ErrorType.Warning);
                        if (result == DialogResult.No)
                        {
                            _isUpdate = false;
                            view.ClearColumnErrors();
                            LoadWorkerSalary();
                            return;
                        }
                        else
                        {
                            _isUpdate = true;
                            gridView1.FocusedRowHandle = i;
                            gridView1.FocusedColumn = e.Column;
                            return;
                        }
                    }
                    workerSalary = ConvertValueForWorkerSalary(workerSalary);
                    if (flag == 0)
                    {
                        var oldEmployeeSalary = _workerSalaryBUS.LoadWSByWorkerSalaryID(workerSalary.WorkersSalaryID);
                        if (!_workerSalaryBUS.UpdateWks(workerSalary))
                        {
                            MessageBox.Show("Không thể cập nhật thông tin", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            _isUpdate = false;
                        }
                        else
                        {
                            alertControlMain.Show(this, Constants.CONFIRM, String.Format("Bạn Đã sửa bảng lương công nhân {0} Thành Công!", workerSalary.Name));
                            
                            _isUpdate = false;
                            _isNew = false;
                            if (oldEmployeeSalary != null)
                            {
                                oldEmployeeSalary.Status = 2;
                                _listSalaryHistory.Add(oldEmployeeSalary);
                            }
                            LoadWorkerSalary();
                           
                        }
                    }
                    else if (flag == 2)
                    {
                        try
                        {
                            // -- load current data for undo funciton--
                            var oldEmployeeSalary = _workerSalaryBUS.LoadWSByWorkerSalaryID(workerSalary.WorkersSalaryID);
                            List<WorkerDTO> listOldWoker = _workerBUS.LoadAllWks(workerSalary.WorkersSalaryID);
                            for (int j = 0; j < listOldWoker.Count; j++)
                            {
                                listOldWoker[j].dayWorking = _workerBUS.LoadAllDaysWorking(listOldWoker[j].WorkerID);
                            }
                            oldEmployeeSalary.listWork = listOldWoker;

                            //-- actived update function--
                            workerSalary.TotalSalary = 0;
                            workerSalary = ConvertValueForWorkerSalary(workerSalary);
                            _workerSalaryBUS.UpdateWks(workerSalary);

                            List<DayWorkingDTO> listDay = TimeForWorkingDay(workerSalary);
                            List<WorkerDTO> listWoker = _workerBUS.LoadAllWks(workerSalary.WorkersSalaryID);
                            _workerBUS.updateAllWks(workerSalary.WorkersSalaryID);
                            foreach (var worker in listWoker)
                            {
                                foreach (var day in listDay)
                                {
                                    day.WorkerID = worker.WorkerID;
                                    _workerBUS.CreateDayWorking(day);
                                }
                            }
                            alertControlMain.Show(this, Constants.CONFIRM, String.Format("Bạn Đã sửa bảng lương công nhân {0} Thành Công!", workerSalary.Name));

                            _isUpdate = false;
                            _isNew = false;
                            LoadWorkerSalary();
                            if (oldEmployeeSalary != null)
                            {
                                oldEmployeeSalary.Status = 3;
                                _listSalaryHistory.Add(oldEmployeeSalary);
                            }
                        }
                        catch
                        {
                            MessageBox.Show("Không thể cập nhật thông tin", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            _isUpdate = false;
                        }

                    }
                    else
                    {
                        _isUpdate = false;
                        _isNew = false;
                        LoadWorkerSalary();
                    }
                }
            }
        }

     

        private void gridView1_InvalidRowException_1(object sender, InvalidRowExceptionEventArgs e)
        {
            e.ExceptionMode = ExceptionMode.NoAction;
        }

        private void bntDelete_ItemClick(object sender, ItemClickEventArgs e)
        {
            int rowIndex = gridView1.FocusedRowHandle;
            var workerSalary = gridView1.GetRow(rowIndex) as WorkerSalaryDTO;
            if (workerSalary != null)
                if (MessageBox.Show(string.Format("Bạn có chắc chắn muốn xóa không?"), "Cảnh báo", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
                {
                    // -- load current data for undo funciton--
                    var oldWorkerSalary = _workerSalaryBUS.LoadWSByWorkerSalaryID(workerSalary.WorkersSalaryID);
                    List<WorkerDTO> listOldWoker = _workerBUS.LoadAllWks(workerSalary.WorkersSalaryID);
                    for (int j = 0; j < listOldWoker.Count; j++)
                    {
                        listOldWoker[j].dayWorking = _workerBUS.LoadAllDaysWorking(listOldWoker[j].WorkerID);
                    }
                    oldWorkerSalary.listWork = listOldWoker;
                    if (oldWorkerSalary != null)
                    {
                        oldWorkerSalary.Status = 4;
                        _listSalaryHistory.Add(oldWorkerSalary);
                    }
                    _workerSalaryBUS.delete(workerSalary.WorkersSalaryID);
                    alertControlMain.Show(this, Constants.CONFIRM, String.Format("Bạn Đã xóa bảng lương công nhân {0} Thành Công!", workerSalary.Name));
                    LoadWorkerSalary();
                }
        }

        private void repositoryItemButtonEdit1_ButtonClick(object sender, ButtonPressedEventArgs e)
        {
            
            int rowIndex = gridView1.FocusedRowHandle;
            var view = sender as ColumnView;
            var workerSalary = gridView1.GetRow(rowIndex) as WorkerSalaryDTO;

 if (workerSalary != null)
            {
                if (workerSalary.WorkersSalaryID > 0)
                {
                    WorkersSalaryDetail ws = new WorkersSalaryDetail(workerSalary);
                    ws.ShowDialog();
                }
                else
                    MessageBox.Show("Bạn phải khởi tạo bảng lương trước khi thực hiện chức năng này.");
            }

            else
                MessageBox.Show("Bạn phải khởi tạo bảng lương trước khi thực hiện chức năng này.");
           

            LoadWorkerSalary();
    }

        private void bntUndo_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (_listSalaryHistory.Count > 0)
            {
                try
                {
                    WorkerSalaryDTO workerSalary = _listSalaryHistory[_listSalaryHistory.Count - 1];
                    if (workerSalary.Status == 1)
                    {
                        _workerSalaryBUS.delete(workerSalary.WorkersSalaryID);
                    }
                    else if (workerSalary.Status == 2)
                    {
                        _workerSalaryBUS.UpdateWks(workerSalary);
                    }
                    else if (workerSalary.Status == 3)
                    {
                        _workerSalaryBUS.delete(workerSalary.WorkersSalaryID);

                        workerSalary.WorkersSalaryID =_workerSalaryBUS.CreateWks(workerSalary);
                       
                        foreach (var worker in workerSalary.listWork)
                        {
                            worker.WorkersSalaryID = workerSalary.WorkersSalaryID;
                            long workerID = _workerBUS.CreateWks(worker);
                            foreach (var day in worker.dayWorking)
                            {
                                day.WorkerID = workerID;
                                _workerBUS.CreateDayWorking(day);
                            }
                        }
                    }
                    else if (workerSalary.Status == 4)
                    {
                        workerSalary.WorkersSalaryID = _workerSalaryBUS.CreateWks(workerSalary);
                 
                        foreach (var worker in workerSalary.listWork)
                        {
                            worker.WorkersSalaryID = workerSalary.WorkersSalaryID;
                            long workerID = _workerBUS.CreateWks(worker);
                            foreach (var day in worker.dayWorking)
                            {
                                day.WorkerID = workerID;
                                _workerBUS.CreateDayWorking(day);
                            }
                        }
                    }
                }
                catch
                {
                    MessageBox.Show("Không thể hồi phục dữ liệu này");
                }
                _listSalaryHistory.RemoveAt(_listSalaryHistory.Count - 1);
            }
            LoadWorkerSalary();

        }

    
    }
}